<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<meta name="description" content="Typogenic documentation.">
		<meta name="author" content="Thomas Hourdel">

		<title>Typogenic Documentation</title>

		<link href="css/bootstrap.min.css" rel="stylesheet">
		<link href="css/main.css" rel="stylesheet">

		<!--[if lt IE 9]>
			<script>
				/*
				 HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
				*/
				(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
				a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x<style>article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}</style>";
				c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="<xyz></xyz>";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
				"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);
				if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d<h;d++)c.createElement(e[d]);return c}};l.html5=e;q(f)})(this,document);
			</script>
			<script>
				/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
				/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
				window.matchMedia=window.matchMedia||function(a){"use strict";var c,d=a.documentElement,e=d.firstElementChild||d.firstChild,f=a.createElement("body"),g=a.createElement("div");return g.id="mq-test-1",g.style.cssText="position:absolute;top:-100em",f.style.background="none",f.appendChild(g),function(a){return g.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',d.insertBefore(f,e),c=42===g.offsetWidth,d.removeChild(f),{matches:c,media:a}}}(document);

				/*! Respond.js v1.3.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs  */
				(function(a){"use strict";function x(){u(!0)}var b={};if(a.respond=b,b.update=function(){},b.mediaQueriesSupported=a.matchMedia&&a.matchMedia("only all").matches,!b.mediaQueriesSupported){var q,r,t,c=a.document,d=c.documentElement,e=[],f=[],g=[],h={},i=30,j=c.getElementsByTagName("head")[0]||d,k=c.getElementsByTagName("base")[0],l=j.getElementsByTagName("link"),m=[],n=function(){for(var b=0;l.length>b;b++){var c=l[b],d=c.href,e=c.media,f=c.rel&&"stylesheet"===c.rel.toLowerCase();d&&f&&!h[d]&&(c.styleSheet&&c.styleSheet.rawCssText?(p(c.styleSheet.rawCssText,d,e),h[d]=!0):(!/^([a-zA-Z:]*\/\/)/.test(d)&&!k||d.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&m.push({href:d,media:e}))}o()},o=function(){if(m.length){var b=m.shift();v(b.href,function(c){p(c,b.href,b.media),h[b.href]=!0,a.setTimeout(function(){o()},0)})}},p=function(a,b,c){var d=a.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),g=d&&d.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+b+"$2$3")},i=!g&&c;b.length&&(b+="/"),i&&(g=1);for(var j=0;g>j;j++){var k,l,m,n;i?(k=c,f.push(h(a))):(k=d[j].match(/@media *([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1,f.push(RegExp.$2&&h(RegExp.$2))),m=k.split(","),n=m.length;for(var o=0;n>o;o++)l=m[o],e.push({media:l.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/)&&RegExp.$2||"all",rules:f.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},s=function(){var a,b=c.createElement("div"),e=c.body,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",e||(e=f=c.createElement("body"),e.style.background="none"),e.appendChild(b),d.insertBefore(e,d.firstChild),a=b.offsetWidth,f?d.removeChild(e):e.removeChild(b),a=t=parseFloat(a)},u=function(b){var h="clientWidth",k=d[h],m="CSS1Compat"===c.compatMode&&k||c.body[h]||k,n={},o=l[l.length-1],p=(new Date).getTime();if(b&&q&&i>p-q)return a.clearTimeout(r),r=a.setTimeout(u,i),void 0;q=p;for(var v in e)if(e.hasOwnProperty(v)){var w=e[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?t||s():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?t||s():1)),w.hasquery&&(z&&A||!(z||m>=x)||!(A||y>=m))||(n[w.media]||(n[w.media]=[]),n[w.media].push(f[w.rules]))}for(var C in g)g.hasOwnProperty(C)&&g[C]&&g[C].parentNode===j&&j.removeChild(g[C]);for(var D in n)if(n.hasOwnProperty(D)){var E=c.createElement("style"),F=n[D].join("\n");E.type="text/css",E.media=D,j.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(c.createTextNode(F)),g.push(E)}},v=function(a,b){var c=w();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},w=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}();n(),b.update=n,a.addEventListener?a.addEventListener("resize",x,!1):a.attachEvent&&a.attachEvent("onresize",x)}})(this); 
			</script>
		<![endif]-->

		<script type="text/javascript">

			var _gaq = _gaq || [];
			_gaq.push(['_setAccount', 'UA-52887212-2']);
			_gaq.push(['_trackPageview']);

			(function() {
				var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
				ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
				var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
			})();

		</script>
	</head>

	<body>
		<div id="wrap">
			<div class="container">
				<div class="page-header">
					<h1>Typogenic Documentation</h1>
				</div>

				<!-- Index -->
				<div id="index">
					<ul>
						<li><a href="#intro">Introduction</a></li>
						<li><a href="#requirements">Requirements</a></li>
						<li><a href="#usage">Usage</a></li>
						<ul>
							<li><a href="#create-font">Creating a New Font</a></li>
							<li><a href="#text-component">Text Component</a></li>
							<li><a href="#font-materials">Font Materials</a></li>
							<li><a href="#mixed-materials">Mixed Materials</a></li>
							<li><a href="#scripting">Scripting Support</a></li>
							<li><a href="#interactivity">Interactivity</a></li>
							<li><a href="#tips">Tips &amp; Tricks</a></li>
						</ul>
						<li><a href="#support">Contact &amp; Support</a></li>
					</ul>
				</div>

				<!-- Introduction & Usage -->
				<div id="intro" class="page-header">
					<h2>Introduction</h2>
				</div>

				<p><strong>Typogenic</strong> is a new high quality and high performances 3D font rendering system for Unity. It's based on a technique called "signed-distance field rendering" used in Team Fortress 2 and documented in <a href="http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf">this Valve paper</a>.</p>

				<!-- Requirements -->
				<div id="requirements" class="page-header">
					<h2>Requirements</h2>
				</div>

				<p>Typogenic requires Unity 4.3+ and works with the free version. It works on desktop as well as mobile platforms.</p>

				<p>The shaders included make use of <strong>Shader Model 3.0</strong> features : NVIDIA cards since 2004 (GeForce 6), AMD cards since 2005 (Radeon X1300), Intel cards since 2006 (GMA X3000), OpenGL ES 2.0, Xbox 360, PS3.</p>

				<!-- Usage -->
				<div id="usage" class="page-header">
					<h2>Usage</h2>
				</div>

				<!-- Creating a New Font -->
				<h3 id="create-font">Creating a New Font</h3>

				<p>At the moment, creating a font with Typogenic is a two steps process : generating the font data and importing it into Unity.</p>

				<p>To generate the font data you'll need to use a free external tool called <a href="http://kvazars.com/littera/">Littera</a>. No installation is needed, it works in the browser assuming you have Flash enabled.</p>

				<p>Let's start with the global settings :</p>

				<img src="img/littera-settings.png" class="img-rounded img-responsive img-center">

				<p></p>

				<p>Make sure the <strong>Format</strong> is set to XML and <strong>Round Values</strong> is disabled or you'll get precision errors. The default <strong>Padding</strong> value of 2 is good, don't go any lower to avoid texture bleeding.</p>

				<div class="alert alert-warning">Size settings are up to you but it's always a good idea to work with <strong>Power of 2</strong> textures, specially if one of your target is a mobile device.</div>

				<p>On to the font settings :<p>

				<img src="img/littera-font.png" class="img-rounded img-responsive img-center">

				<p></p>

				<p>These are the only three panels you'll need to generate the font. Good all-around settings :</p>

				<ul>
					<li><strong>Font Size :</strong> 64</li>
					<li><strong>Distance Field Type :</strong> 2</li>
					<li><strong>Distance Field Quality :</strong> 6</li>
					<li><strong>Distance Field Spread :</strong> 20</li>
				</ul>

				<p>Although these settings generally give good results with most typefaces, they might not work in every case scenario. See the <a href="#tips">Tips &amp; Tricks</a> section.</p>

				<div class="alert alert-warning">Forget about <strong>Letter Spacing</strong> for now, it can be changed dynamically via Typogenic in Unity3D.</div>

				<div class="alert alert-warning">Keep the background <strong>transparent</strong> !</div>

				<p>Depending on your computer speed, Littera will take a few seconds to generate the font (a progress bar can be seen in the bottom right corner). Once it's done, <strong>Export</strong> it. Littera outputs a <em>.zip</em> file containing both <em>.fnt</em> and <em>.png</em> files. Copy these two into your Unity project.</p>

				<p>Assuming you've already imported the Typogenic package into Unity, go to <em>Assets -> Create -> Typogenic Font</em> to open the font wizard.</p>

				<img src="img/font-wizard.png" class="img-rounded img-responsive img-center">

				<p></p>

				<p>Drag the font texture from the project panel into <strong>Atlas</strong> and the <em>.fnt</em> file into <strong>Font XML</strong> and click the <strong>Create</strong>. By default, the wizard will automatically create a material and change the import settings for the font texture. You can choose to disable both these options.</p>

				<p>Your font is ready to use !</p>

				<p class="text-center"><a href="#wrap">Back to top</a></p>

				<!-- Text Component -->
				<h3 id="text-component">Text Component</h3>

				<p>To put a new text object on the scene, go to <em>Game Object -> Create Other -> Typogenic Text</em>. <mark>Drag the font material onto the object</mark> and add the font asset file generated by the wizard into the <strong>Font</strong> field of the <strong>Typogenic Text</strong> component.</p>

				<img src="img/text-settings.png" class="img-rounded img-responsive img-center">

				<p></p>

				<p>Most of the settings are self-explanatory. To enable word wrapping, set <strong>Word Wrap</strong> to the desired width. A visual indicator will appear in the scene view to give you an idea about where the text will wrap. Set it to 0 or less to disable it.</p>

				<p>Using the <strong>Fill Mode</strong> you can add a horizontal, vertical or quad gradient to every character or use a texturing method (don't forget to use a textured material).</p>

				<p>All the settings in this component are, of course, available via scripting as well.</p>

				<div class="alert alert-warning">
					<p>If you don't need lighting on your text, disable <strong>Generate Normals</strong> to save some memory at runtime.</p>
					<p>If you don't need <strong>Click Support</strong>, disable it to improve performances. If you need click support and your text object isn't going to be moved/rotated around the scene, make sure <strong>Static</strong> is checked to avoid unnecessary bounds calculations.</p>
				</div>

				<p class="text-center"><a href="#wrap">Back to top</a></p>

				<!-- Font Materials -->
				<h3 id="font-materials">Font Materials</h3>

				<p>Typogenic comes with a few shaders : lit, unlit, texture &amp; shadow caster variants. By default, the font wizard generates an unlit untextured material but you can swap it to another shader depending on your needs. Make sure you set <strong>Generate Normals</strong> on every <strong>Typogenic Text</strong> that makes use of one the lit shaders.</p>

				<img src="img/material.png" class="img-rounded img-responsive img-center">

				<p></p>

				<p>The <strong>Smoothness</strong> parameter allows you to sharpen or slightly blur the text borders. A value between 0.85 and 1.0 should give the best result.</p>

				<p><strong>Thickness</strong> controls the font weight to make the text bolder or thinner, up to a certain point.</p>

				<p>You can also enable <strong>Outlines</strong> and control their <strong>Thickness</strong> and <strong>Color</strong>. The <strong>Thickness</strong> parameter will be limited by the spread amount used in the <strong>Distance Field</strong> panel of Littera. You can offset the <strong>Outlines</strong> by playing with both <strong>Thickness</strong> values.</p>

				<p>Like the outlines, the <strong>Glow</strong> spread will be limited by the spread amount used in the <strong>Distance Field</strong> panel of Littera.</p>

				<p>The <strong>Global Color Multiplier</strong> can be used to quickly change the text color or alpha without rebuilding the mesh, which can be useful to do quick animated color or fade effects. It applies to the outlines as well, if any. Set it to full-white full-opaque to disable it.</p>

				<img src="img/material-texture.png" class="img-rounded img-responsive img-center">

				<p></p>

				<p>If you chose a textured <strong>Fill Mode</strong> make sure you switch to a textured shader. It will add a <strong>Fill Texture</strong> field to the material which works the same way any other textured material does in Unity.</p>

				<img src="img/material-shadow.png" class="img-rounded img-responsive img-center">

				<p></p>

				<p>When working with a shadow casting material you'll also get the ability to adjust the shadow cutoff. The default value should be fine but you can tweak it to get thinner or larger shadows.</p>

				<p class="text-center"><a href="#wrap">Back to top</a></p>

				<!-- Mixed Materials -->
				<h3 id="mixed-materials">Mixed Materials</h3>

				<p>You can mix up to nine materials within the same text component using a simple formatting trick.</p>

				<img src="img/material-mixed.png" class="img-rounded img-responsive img-center">

				<p></p>

				<p>Assign a bunch of materials into the <strong>Materials</strong> array of your <strong>Mesh Renderer</strong> component. Keep track of each material index in the list (<strong>Element 0</strong>, <strong>Element 1</strong>, etc) and use them with an back-slash to activate them where you need them. Like so :</p>

				<pre>\0Nice \1and \2colorful !</pre>

				<p>Assuming material <strong>0</strong> is red, <strong>1</strong> is green and <strong>2</strong> is blue, it will display a red, green and blue line of text.

				<p class="text-center"><a href="#wrap">Back to top</a></p>

				<!-- Scripting Support -->
				<h3 id="scripting">Scripting Support</h3>

				<p>Typogenic comes with a full public interface to interact with the component at runtime.</p>

				<p>Unless you set <code>AutoRebuild</code> to <code>false</code> the component will automatically detect any change in the text settings and rebuild the mesh at the end of the frame.</p>

				<pre>var component = GetComponent&lt;TypogenicText&gt;();
component.Text = "Lorem ipsum";
component.Size = 24f;</pre>

				<p>You also set most of the settings in one-go using the <code>Set()</code> method with named parameters :</p>

				<pre>var component = GetComponent&lt;TypogenicText&gt;();
component.Set(
  text: "Lorem Ipsum",
  alignement: TTextAlignment.Center,
  size: 24f
);</pre>

				<p>Take a look at the <strong>TypogenicText.cs</strong> file for a list of public methods and properties, or use your favorite IDE with auto-completion.</p>

				<div class="alert alert-warning">If your text is static or rarely changed it's recommended to set <code>AutoRebuild</code> to <code>false</code> so the component don't have to keep track of its current state and call <code>RebuildMesh()</code> when you need it.</div>

				<div class="alert alert-warning">
					About the colors, <code>TypogenicText</code> comes with four color fields which are used in the following ways depending on which <code>TFillMore</code> you choose :<br><br>

					<ul>
						<li>Single : <code>ColorTopLeft</code>.</li>
						<li>Vertical Gradient : <code>ColorTopLeft</code> &amp; <code>ColorBottomLeft</code>.</li>
						<li>Horizontal Gradient : <code>ColorTopLeft</code> &amp; <code>ColorTopRight</code>.</li>
						<li>QuadGradient : All four fields.</li>
					</ul>
				</div>

				<p class="text-center"><a href="#wrap">Back to top</a></p>

				<!-- Interactivity -->
				<h3 id="interactivity">Interactivity</h3>

				<p>Typogenic lets you detect individual character clicks. To do so, make sure your text has a collider (a simple box is fine, no need for a complex mesh collider). Typogenic will then broadcast a <code>OnGlyphClicked</code> message along with a <code>TypogenicGlyphClickEvent</code>.</p>

				<pre>using UnityEngine;

public class ClickHandler : MonoBehaviour
{
	void OnGlyphClicked(TypogenicGlyphClickEvent e)
	{
		Debug.Log(string.Format(
			"Clicked {0} at character index {1}",
			e.source.name,
			e.index
		));
	}
}</pre>

				<p>Once you've got the character index you can easily extract which character, word or line has been clicked. See <strong>Demo 9</strong> and <em>ClickHandler.cs</em> in the <em>/Typogenic/Demo</em> folder for a more complete example.</p>

				<p class="text-center"><a href="#wrap">Back to top</a></p>

				<!-- Tips & Tricks -->
				<h3 id="tips">Tips &amp; Tricks</h3>

				<ul>
					<li>If you need bigger outlines, use a larger spread when generating the font in the <strong>Distance Field</strong> panel of Littera. You'll experience a small loss of quality on close-ups but it shouldn't be that bad, the oulines will help cover it.</li>
					<li>If you don't need to display huge characters on screen you can safely drop the font size to 32 or 24 in Littera. You'll have to lower the spread as well.</li>
					<li>
						If you need a wide range of zooms and rotations with 3D text, it would be best to change the texture import settings on the font atlas :
						<ul>
							<li><strong>Generate Mipmaps :</strong> enabled</li>
							<li><strong>Mip Map Filtering :</strong> Kaiser</li>
							<li><strong>Filter Mode :</strong> Trilinear</li>
							<li><strong>Aniso Level :</strong> As high as you can</li>
						</ul>
						This should help reduce the wiggling effect with extreme transformations.
					</li>
					<li>Don't forget you can use the alpha values on the text color / gradient and the outlines as well !</li>
				</ul>

				<p class="text-center"><a href="#wrap">Back to top</a></p>

				<!-- Contact & Support -->
				<div id="support" class="page-header">
					<h2>Contact &amp; Support</h2>
				</div>

				<p>If you have any questions or feedback, you can contact me at :</p>

				<ul>
					<li>E-mail : <a href="mailto:thomas.hourdel@gmail.com">thomas.hourdel@gmail.com</a></li>
					<li>Twitter : <a href="http://www.twitter.com/Chman">@Chman</a></li>
					<li>Unity Community : <a href="http://forum.unity3d.com/members/15388-Chman">Chman</a></li>
				</ul>

				<p>Quick links :</p>

				<ul>
					<li><a href="https://www.assetstore.unity3d.com/en/#!/content/19182">Asset Store Page</a> (leave a review!)</li>
					<li><a href="https://github.com/Chman/Typogenic">GitHub</a></li>
					<li><a href="http://forum.unity3d.com/threads/typogenic-advanced-text-rendering-free.254978/">Support Forum</a></li>
					<li>Like Typogenic ? Check out my other <a href="https://www.assetstore.unity3d.com/en/#!/publisher/1627">Unity Assets</a></li>
				</ul>
			</div>

			<div id="footer">
				<div class="container">
					<p class="text-muted credit">Typogenic Documentation &middot; &copy; <a href="http://www.thomashourdel.com">Thomas Hourdel</a></p>
				</div>
			</div>
		</div>
	</body>
</html>
